<?php

use Workerman\Worker;
use Workerman\Mysql;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

//全局数据库函数
function sql_query($sql, &$errorMessage =""){
    // var_dump(999,$sql,999);
    return sql_common("query", $sql);
}

function sql_common($fun, $sql){
   try{
        if($fun == "queryIdx"){
            $ret = Mysql::instance(G_DB_MES_INSTANCE, G_DB_MES_CONFIG)->query($sql, null, PDO::FETCH_NUM);;
        }else{
            $ret = Mysql::instance(G_DB_MES_INSTANCE, G_DB_MES_CONFIG)->$fun($sql);
        }
        return $ret; 
    }catch(Exception $e){
        if($e->getCode() == 2003 || $e->getCode() == 2006 || $e->getCode() == 2013 || $e->errorInfo[1] == 2003 || $e->errorInfo[1] == 2006 || $e->errorInfo[1] == 2013){
            $ret = sql_reConnnect($fun, $sql);
            return $ret;
        }
        Debug::Assert($e->getMessage(),$sql);
        $errorMessage = $e->getMessage();
        return null;
    }catch(\ErrorException  $ee){
        var_dump($fun,'12333333333333');
        var_dump($ee->getMessage(),'121212');
    }
    
}


/**
 * 执行SQL返回第一行
 *
 * @param string $sql
 * @param array $params
 * @return mixed
 */
function sql_fetch( $sql, &$errorMessage =""){
    if(strpos(strtolower($sql), "limit")==false)
        $sql = rtrim($sql, ";") . " limit 1;";
    $ret = sql_query($sql);
    if(count($ret)>0){
        return $ret[0];
    }else{
        return null;
    }
}


function sql_fetchAll ( $sql, &$errorMessage =""){
    if(strpos(strtolower($sql), "limit")==false)
        $sql = rtrim($sql, ";") ;
    $ret = sql_query($sql);
    if(count($ret)>0){
        return $ret[0];
    }else{
        return null;
    }
}

function sql_reConnnect($fun, $sql){
    
    $ret = null;
    //重连次数
    $reconnect_num = 3;
    $i = 0;
    do{
        try{
            sleep(0.1);
            Mysql::close(G_DB_MES_INSTANCE);
            if($fun == "queryIdx"){
                $ret = Mysql::instance(G_DB_MES_INSTANCE, G_DB_MES_CONFIG)->query($sql, null, PDO::FETCH_NUM);;
            }else{
                $ret = Mysql::instance(G_DB_MES_INSTANCE, G_DB_MES_CONFIG)->$fun($sql);
            }
            return $ret;
            
        }catch(Exception $e){
            if($e->getCode() == 2003 || $e->getCode() == 2006 || $e->getCode() == 2013 || $e->errorInfo[1] == 2003 || $e->errorInfo[1] == 2006 || $e->errorInfo[1] == 2013){
                $i ++;
            }else{
                $i = $reconnect_num+1;
            }
            Debug::Assert($e->getMessage(),$sql);
            $errorMessage = $e->getMessage();
        }
    }while($i<$reconnect_num);
    // 三次请求后仍然失败，跳出异常

    throw new PDOException("Sql_reConnnect command fail in ".$reconnect_num." times[" . $e->getMessage() . "] func = [".$fun."] sql = [". $sql ."]");
    
}

// 兼容web接口代码
function sql_insert($table, $data){
    $key_str = "";
    $val_str = "";
    foreach($data as $key => $val){
        $key_str .= "`".$key . "`,";
        $val_str .= "'".$val."',";
    }
    $key_str = rtrim($key_str, ",");
    $val_str = rtrim($val_str, ",");
    
    $sql = "INSERT INTO `$table` ($key_str) VALUES ($val_str)";
    return sql_common("query", $sql);
    
}


function sql_update($table, $data= array(), $params= array()){
    $str = "";
    foreach($data as $key => $val){
        $str .= "`".$key . "`='$val',";
    }
    $str = rtrim($str, ",");
    $sql = "UPDATE `$table` SET $str ";
    $sql .= " WHERE ";

    $count = 0 ;
    foreach($params as $k=>$v){
        $count++;
        if($count===count($params)){
            $sql .= "`$k`='$v' ";
        }else{
            $sql .= "`$k`='$v' AND ";
        }
    }
    var_dump( 888,$sql ,888 );
    return sql_common("query", $sql);
}



function sql_delete($table, $id){
    $key = key($id);
    $val = $id[$key];
    $sql = "DELETE FROM  `$table` WHERE $key='$val'";
    return sql_common("query", $sql);
}

function sql_lastInsertId(){
    return sql_common("lastInsertId", "");
}

function sql_queryIdx($sql, &$errorMessage = ""){
    return sql_common("queryIdx", $sql);
}

function sql_queryExec($sql){
    return sql_common("queryExec", $sql);
}

function sql_beginTrans(){
    return sql_common("beginTrans", "");
}

function sql_commitTrans(){
    return sql_common("commitTrans", "");
}

function sql_rollBackTrans(){
    return sql_common("rollBackTrans", "");
}

/**
 * 检查数据表唯一值
 *
 * @param $tb 表名称，$id输入的id（非nul为修改，nul为新加）,$data 检查的值，$key 数据字段
 * @return string
 */
function checkUniqueValue_jsValidate($tb, $id, $data, $key)
{
    if(empty($id)){
        $sql = "select id from $tb where $key='". $data ."' limit 1;";
        $dp=sql_common("query", $sql);
        if(!empty($dp)){
            return 'false';
        }
    }else{
        //修改用户的时候的检查
        $sql = "select id from $tb where id != ".$id." and $key='". $data ."' limit 1;";
        $dp=sql_common("query", $sql);
        if(!empty($dp)){
            return 'false';
        }
    }
    return "true";  
}


/**
 * 数组 转 对象
 *
 * @param array $arr 数组
 * @return object
 */
function array_to_object($arr) {
    if (gettype($arr) != 'array') {
        return;
    }
    foreach ($arr as $k => $v) {
        if (gettype($v) == 'array' || getType($v) == 'object') {
            $arr[$k] = (object)array_to_object($v);
        }
    }
 
    return (object)$arr;
}


function create_folder($path)
{
    if (!file_exists($path))
    {
        create_folder(dirname($path));
        mkdir($path, 0777);
        chmod($path, 0777);
    }
}


function get_closest($search, $arr) {
   $closest = null;
   foreach ($arr as $item) {
      if ($closest === null || abs($search - $closest) > abs($item - $search)) {
         $closest = $item;
      }
   }
   return $closest;
}


function curl_open($url, $type, $data = ""){
    $ch = curl_init();
    $timeout  = 1;
    curl_setopt( $ch , CURLOPT_TIMEOUT, $timeout );
    curl_setopt( $ch , CURLOPT_CONNECTTIMEOUT_MS, 200);
    curl_setopt( $ch , CURLOPT_HEADER, false);
    curl_setopt( $ch , CURLOPT_URL, $url);
    curl_setopt( $ch , CURLOPT_RETURNTRANSFER, 1);
    if($type == "POST"){
        curl_setopt( $ch , CURLOPT_POST, 1);
        // curl_setopt($ch,CURLOPT_HTTPHEADER,array ( "Accept: application/json" ));
        curl_setopt($ch,CURLOPT_HTTPHEADER,array('Content-Type: application/json')); 
        curl_setopt( $ch , CURLOPT_POSTFIELDS, $data);
    }else{
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1); // 从证书中检查SSL加密算法是否存在
        curl_setopt($ch, CURLOPT_SSLVERSION, 3);
    }
    $output = curl_exec($ch);
    
    
    
    curl_close($ch);
    if($output!=""){
        $val = json_decode($output,true);
        return $val;
    }else{
        return array("statusCode"=>4002, "statusMessage"=>"WCS Timeout", "rtval"=>null);
    }
     
}

function file_write($path, $context){
    $fh = fopen($path, "w") or die("Unable to open file!");
    fwrite($fh, $context);
    fclose($fh);    
    
}


function num_format($num, $bit){
    return substr(sprintf ("%01.9f",$num),0,$bit);
}

// guid生成
function guid(){
    mt_srand((double)microtime()*10000);//optional for php 4.2.0 and up.
    $charid = strtoupper(md5(uniqid(rand(), true)));
    $uuid = substr($charid, 0, 8)
        .substr($charid, 8, 4)
        .substr($charid,12, 4)
        .substr($charid,16, 4)
        .substr($charid,20,12);
    return $uuid;
}




/**
 * 供HandleSocket调用数据排序
 *
 * @param $data
 */ 
function sortByPk(&$data)
{
    usort($data, function ($a, $b) {
        if ($a[0] == $b[0]) {
            return 0;
        }
        return $a[0] > $b[0] ? -1 : 1;
    });
}

/**
 * 生成唯一订单号
 *
 * @return string
 */
function get_order_sn()
{
    return date('Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
}

/**
 * 从$_GET/$_POST/$_COOKIE中获取值
 *
 * @param $k
 * @param string $t
 * @return null
 */
function getgpc($k, $t = 'GP')
{
    $t = strtoupper($t);
    switch ($t) {
        case 'GP' :
            isset($_POST[$k]) ? $var = &$_POST : $var = &$_GET;
            break;
        case 'G':
            $var = &$_GET;
            break;
        case 'P':
            $var = &$_POST;
            break;
        case 'C':
            $var = &$_COOKIE;
            break;
        case 'R':
            $var = &$_REQUEST;
            break;
    }
    return isset($var[$k]) ? $var[$k] : null;
}

function get_session($k)
{
    return isset($_SESSION[$k]) ? $_SESSION[$k] : NULL;
}

/**
 * 格式化价格
 *
 * @param $price
 * @param bool $change_price
 * @param int $format
 * @return string
 */
function price_format($price, $change_price = false, $format = 0)
{
    if ($price === '') {
        $price = 0;
    }
    if ($change_price) {
        switch ($format) {
            case 0:
                $price = number_format($price, 2, '.', '');
                break;
            case 1: // 保留不为 0 的尾数
                $price = preg_replace('/(.*)(\\.)([0-9]*?)0+$/', '\1\2\3', number_format($price, 2, '.', ''));

                if (substr($price, -1) == '.') {
                    $price = substr($price, 0, -1);
                }
                break;
            case 2: // 不四舍五入，保留1位
                $price = substr(number_format($price, 2, '.', ''), 0, -1);
                break;
            case 3: // 直接取整
                $price = intval($price);
                break;
            case 4: // 四舍五入，保留 1 位
                $price = number_format($price, 1, '.', '');
                break;
            case 5: // 先四舍五入，不保留小数
                $price = round($price);
                break;
        }
    } else {
        $price = number_format($price, 2, '.', '');
    }

    return $price;
}

/**
 * 检查数据表唯一值
 *
 * @param $tb 表名称，$id输入的id（非nul为修改，nul为新加）,$data 检查的值，$key 数据字段
 * @return string
 */
function checkUniqueValue_jsValidate1($tb, $id, $data, $key)
{
 if(empty($id)){
     $sql = "select id from $tb where $key='". $data ."' limit 1;";
     $dp=pdo_fetch($sql);
     if(!empty($dp)){
         echo 'false';
         Workerman\Protocols\Http::end();
     }
 }else{
     //修改用户的时候的检查
     $sql = "select id from $tb where id != ".$id." and $key='". $data ."' limit 1;";
     $dp=pdo_fetch($sql);
     if(!empty($dp)){
         return 'false';
         Workerman\Protocols\Http::end();
     }
 }
 return "true";
 Workerman\Protocols\Http::end();    
}


/**
 * 判断是否是合法的IP地址函数
 *
 * @param $ip
 * @return true/false
 */
function is_ipAddress($ip){
    if(preg_match('/^((?:(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(?:25[0-5]|2[0-4]\d|((1\d{2})|([1 -9]?\d))))$/', $ip))
    {
        return true;
    }else{
        return false;
    }
}



function http_request( $url, $post = '', $timeout = 5 ){ 
    if( empty( $url ) ){
        return ;
    }
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
     
    if( $post != '' && !empty( $post ) ){
         curl_setopt($ch, CURLOPT_POST, 1);
         curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
         curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Content-Length: ' . strlen($post)));
    }
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}


function create_folder2($path)
{
    if (!file_exists($path))
    {
        create_folder2(dirname($path));
        mkdir($path, 0777);
        chmod($path, 0777);
    }
}



function sendMail($to, $title, $content)
{
    //实例化PHPMailer核心类
    $mail = new PHPMailer();
     
    //是否启用smtp的debug进行调试 开发环境建议开启 生产环境注释掉即可 默认关闭debug调试模式
    //$mail->SMTPDebug = 1;
     
    //使用smtp鉴权方式发送邮件
    $mail->isSMTP();
     
    //smtp需要鉴权 这个必须是true
    $mail->SMTPAuth=true;

    //Timeout设置SMTP服务器的超时(单位：秒)
    $mail->Timeout=1;
    $mail->Timelimit=1;
    //链接qq域名邮箱的服务器地址
    $mail->Host = 'smtp.qq.com';
     
    //设置使用ssl加密方式登录鉴权
    $mail->SMTPSecure = 'ssl';
     
    //设置ssl连接smtp服务器的远程服务器端口号 可选465或587
    $mail->Port = 465;
     
    //设置smtp的hello消息头 这个可有可无 内容任意
    $mail->Helo = 'Welcome smtp.qq.com Richard';
     
    //设置发件人的主机域 可有可无 默认为localhost 内容任意，建议使用自己的域名
    $mail->Hostname = 'http://www.aop.com';
     
    //设置发送的邮件的编码 可选GB2312 或utf-8 测试发现utf8在360浏览器收信下可能会乱码
    $mail->CharSet = 'UTF-8';
     
    //设置发件人姓名（昵称） 任意内容，显示在收件人邮件的发件人邮箱地址前的发件人姓名
    $mail->FromName = '系统自动发送，请勿回复';
     
    //smtp登录的账号 这里填入字符串格式的QQ号即可,x代表阿拉伯数字（你的QQ号）
    $mail->Username ='1753858361';
     
    //smtp登录的密码；使用生成的授权码（就刚才叫你保存的最新的授权码）不要听信什么这那的“独立密码”，//因为我测试报错提示就是SMTP授权码不正确,x代表授权码（刚让保存的）
    $mail->Password = 'eddonmplnajqefce';
     
    //设置发件人邮箱地址 这里填入上述提到的“发件人邮箱”,x代表阿拉伯数字（你的QQ号）
    $mail->From = '1753858361@qq.com';
     
    //邮件正文是否为html编码 注意此处是一个方法 不再是属性 true或false
    $mail->isHTML(true); 
     
    //设置收件人邮箱地址 该方法有两个参数 第一个参数为收件人邮箱地址 第二参数为给该地址设置的昵称 不同的邮箱系统会自动进行处理变动 第二个参数会在发送成功的邮件收件人那边显示
    foreach($to as $e){
        $mail->addAddress($e,'xxx163邮箱');
    }
    
    //添加多个收件人 则多次调用方法即可
    //$mail->addAddress('xxxxxx@gmail.com','xxxGooGle邮箱');
     
    //添加该邮件的主题
    $mail->Subject = $title;
     
    //添加邮件正文 上方将isHTML设置成了true，则可以是完整的html字符串 如：使用file_get_contents函数读取本地的html文件
    $mail->Body = $content;
     
    //为该邮件添加附件 该方法也有两个参数 第一个参数为附件存放的目录（相对目录、或绝对目录均可） 第二参数为在邮件附件中该附件的名称
    //$mail->addAttachment('./apply/aop.zip','login.zip');
     
    //同样该方法可以多次调用 上传多个附件
    //$mail->addAttachment('./apply/img/1.png','1.png');
     
    //发送命令 返回布尔值 
    //PS：经过测试，如果收件人不存在，若不出现错误依然返回true 也就是说在发送之前 自己需要些方法实现检测该邮箱是否真实有效
    $start_time = time();
    $status = $mail->send();
    //简单的判断与提示信息
    if($status) {
        return true;
    } else {
        var_dump("end_end:".(time()-$start_time).",status:".$mail->ErrorInfo);
        return false;
    }
}



















?>